package com.sinosoft.sinopay.apiservice.batchpay.service.impl;

import com.sinosoft.sinocloud.platform.common.util.DateUtil;
import com.sinosoft.sinopay.api.common.dto.pay.PaymentInfoDetailDTO;
import com.sinosoft.sinopay.api.pay.service.ResolveBatchTxtService;
import com.sinosoft.sinopay.paytrade.dto.PaymentTradeBatchDTO;
import com.sinosoft.sinopay.paytrade.dto.PaymentTradeReqDTO;
import com.sinosoft.sinopay.paytrade.facade.PaymentTradeFacadeService;
import com.sinosoft.sinopay.paytrade.facade.PaymentTradeQueryFacadeService;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.expression.ParseException;
import org.springframework.stereotype.Service;

import javax.mail.MessagingException;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * 【 支付平台FTP下载回盘文件 】
 *
 * @author chenzhiheng
 * @version V1.0
 * @date 16/12/22
 */
@Service
public class ResolveBatchTxtServiceImpl implements ResolveBatchTxtService {

    private static Logger logger ;

    @Autowired
    private PaymentTradeFacadeService paymentTradeFacadeService;

    @Autowired
    private PaymentTradeQueryFacadeService paymentTradeQueryFacadeService;

    private String resultStr ;//回盘信息

    @Override
    public void resolveBatchTxt(Integer bankCode) throws ParseException, IOException, MessagingException {
        logger.info("——————————————————解析开始——————————————————");
        String fileName = paymentTradeQueryFacadeService.queryOfferFileNameByOfferPayChannelId(bankCode);
        String strencoding = "GBK"; //文件编码
        String ip = "118.178.128.68 "; // 服务器IP地址
        int port = 21; // 端口号
        String userName = "tomcat"; // 用户名
        String userPwd = "!Tomcat123456!"; // 密码
        String path = "/ftp/unresolved/"; // 读取文件的存放目录
        FTPClient ftpClient = new FTPClient();
        InputStream ins = null;
        try {
            ftpClient.connect(ip, port);// 连接FTP服务器
            ftpClient.login(userName, userPwd);// 登录FTP服务器
            ins = ftpClient.retrieveFileStream(fileName);
            if (ins != null) {
                ftpClient.deleteFile(fileName);
                ins.close();
                ftpClient.connect(ip, port);// 连接FTP服务器
                ftpClient.login(userName, userPwd);// 登录FTP服务器
            }
            ftpClient.changeWorkingDirectory(path);// 跳转到指定目录
            // 从服务器上读取指定的文件
            ins = ftpClient.retrieveFileStream(fileName);
            if (ins != null) {
                List<PaymentTradeReqDTO> paymentTradeReqDTOList = new ArrayList<PaymentTradeReqDTO>();
                PaymentTradeReqDTO paymentTradeReqDTO = new PaymentTradeReqDTO();
                InputStreamReader is = new InputStreamReader(ins, strencoding);
                BufferedReader reader = new BufferedReader(is);
                String lineTxt = null;
                if("0000".equals(bankCode)) {
                    lineTxt = reader.readLine();
                    String[] lt = lineTxt.split("\\|");
                    PaymentTradeBatchDTO paymentTradeBatch = new PaymentTradeBatchDTO();
                    paymentTradeBatch.setTradeAmount(new BigDecimal(lt[7]));
                    paymentTradeBatch.setTradeNum(Integer.parseInt(lt[9]));
                    resultStr = "总笔数: " + lt[9] + "成功笔数: " + lt[10] + "总金额: " + lt[7] + "成功金额: " + lt[8];
                    while ((lineTxt = reader.readLine()) != null) {
                        String[] ltt = lineTxt.split("\\|");
                        if (ltt.length >= 2) {
                            paymentTradeReqDTO.setPayAccountNo(ltt[4]);
                            paymentTradeReqDTO.setPayAccountName(ltt[5]);
                            paymentTradeReqDTO.setPayAmount(new BigDecimal(ltt[5]));
                            paymentTradeReqDTO.setReturnCode(ltt[7]);
                            paymentTradeReqDTO.setReturnMsg(ltt[8]);
                            paymentTradeReqDTOList.add(paymentTradeReqDTO);
                        }
                    }
                }
                if("8888".equals(bankCode)){
                    lineTxt = reader.readLine();
                    String[] lt = lineTxt.split("\\|");
                    PaymentTradeBatchDTO paymentTradeBatch = new PaymentTradeBatchDTO();
                    paymentTradeBatch.setTradeNum(Integer.parseInt(lt[3]));
                    paymentTradeBatch.setTradeAmount(new BigDecimal(lt[5]));
                    resultStr = "总笔数: " + lt[3] + "成功笔数: " + lt[4] + "总金额: " + lt[5] + "成功金额: " + lt[6];
                    while ((lineTxt = reader.readLine()) != null) {
                        String[] ltt = lineTxt.split("\\|");
                        if (ltt.length >= 2) {
                            paymentTradeReqDTO.setReturnCode(ltt[2]);
                            paymentTradeReqDTO.setPayAccountNo(ltt[3]);
                            paymentTradeReqDTO.setPayAmount(new BigDecimal(ltt[4]));
                            paymentTradeReqDTO.setPayAccountName(ltt[6]);
                            paymentTradeReqDTO.setReturnMsg(ltt[11]);
                            paymentTradeReqDTOList.add(paymentTradeReqDTO);
                        }
                    }
                }
                logger.info("——————————————————解析成功——————————————————");
                reader.close();
                ins.close();
                // 主动调用一次getReply()把接下来的226消费掉. 解决返回null问题
                ftpClient.getReply();
                boolean flag = getPaymentInfo(paymentTradeReqDTOList,bankCode);
                if(!flag){
                    throw new MessagingException("修改回盘数据出错!");
                }
            } else {
                logger.info("——————————————————文件未找到！——————————————————");
                throw new MessagingException("文件未找到！");
            }
        } catch (IOException e) {
            logger.info("——————————————————文件解析错误——————————————————");
            ftpClient.rename(path + fileName,  fileName);
            String emailContent = "批量文件解析错误提醒：日期：" + bankCode + "。批量文件解析错误！文件名：" + fileName + ",请注意查看！";
            logger.info(emailContent);
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //修改回盘数据
    public boolean getPaymentInfo(List<PaymentTradeReqDTO> paymentTradeReqList,Integer bankCode) throws Exception {
        boolean result = true;
        List<PaymentTradeReqDTO> paymentTradeReqDTOList = paymentTradeQueryFacadeService.queryAllPayOrderBatchesOfDay(bankCode.toString());
        PaymentTradeReqDTO  paymentTradeReqDTO ; // 修改批次信息数据
        PaymentTradeReqDTO repPaymentMain = new PaymentTradeReqDTO();// 支付交易表数据
        PaymentTradeReqDTO paymentTradeMain = new PaymentTradeReqDTO(); //支付交易与批次关联数据
        PaymentTradeBatchDTO tradeBatch = new PaymentTradeBatchDTO(); //报盘记录信息
        PaymentTradeBatchDTO tradePaymentBatch = new PaymentTradeBatchDTO(); //报盘记录总表信息
        for(int i=0;i<paymentTradeReqDTOList.size();i++) {
            paymentTradeReqDTO = paymentTradeReqDTOList.get(i);
            if(paymentTradeReqDTO.getDealDate() == null) {
                paymentTradeReqDTO.setDealDate(DateUtil.getCurrentDate());
                paymentTradeReqDTO.setResultDesc("2");
                int resultBatch = paymentTradeFacadeService.modifyTransOrderBatchInfo(paymentTradeReqDTO);
                if (resultBatch < 1) {
                    throw new Exception("修改批次表回盘数据失败!");
                }
                tradePaymentBatch.setPayBatchNo(paymentTradeReqDTO.getBatchNo());
                tradePaymentBatch.setReturnTime(DateUtil.getCurrentDate());
                tradePaymentBatch.setResultDesc(resultStr);
                int resultInfo = paymentTradeFacadeService.modifyBatchPaymentInfo(tradePaymentBatch);
                if(resultInfo != 1){
                    throw new Exception("修改交易总表数据失败!");
                }
                tradeBatch.setPayBatchNo(paymentTradeReqDTO.getBatchNo());
                tradeBatch.setReturnTime(DateUtil.getCurrentDate());
                tradeBatch.setOfferFileStatus("2");
                tradeBatch.setResultDesc(resultStr);
                int resultTrade = paymentTradeFacadeService.modifyOfferRecordData(tradeBatch);
                if(resultTrade != 1){
                    throw new Exception("修改报盘记录表数据失败!");
                }
            }
        }
        //修改支付交易表数据
        List<PaymentInfoDetailDTO> paymentMains = paymentTradeQueryFacadeService.queryAllPayTransInfoForDay(bankCode.toString());
        for (int j = 0; j < paymentTradeReqList.size(); j++) {
            for(int k = 0;k < paymentMains.size(); k++){
                if(paymentTradeReqList.get(j).getPayAccountName() == paymentMains.get(k).getAccountName() &&
                        paymentTradeReqList.get(j).getPayAmount() == paymentMains.get(k).getPayAmount() &&
                        paymentTradeReqList.get(j).getPayAccountNo()== paymentMains.get(k).getAccountNo()) {
                    repPaymentMain.setBatchNo(paymentMains.get(k).getReqBatchNo());
                    repPaymentMain.setResultCode(paymentTradeReqList.get(j).getResultCode());
                    repPaymentMain.setResultDesc(paymentTradeReqList.get(j).getResultDesc());
                    int resultMain = paymentTradeFacadeService.modifyTransePayRelate(repPaymentMain);
                    if (resultMain < 1) {
                        throw new Exception("修改支付交易数据失败!");
                    }
                    paymentTradeMain.setBatchNo(paymentMains.get(k).getReqBatchNo());
                    paymentTradeMain.setReturnTime(DateUtil.getCurrentDate());
                    paymentTradeMain.setResultCode(paymentTradeReqList.get(j).getResultCode());
                    paymentTradeMain.setResultDesc(paymentTradeReqList.get(j).getResultDesc());
                    int resultRela = paymentTradeFacadeService.modifyPaymentInfo(paymentTradeMain);
                    if(resultRela != 1){
                        throw new Exception("修改交易支付表数据失败!");
                    }
                }
            }
        }
        return result;
    }

}
